#include "Rational.h"

Rational::Rational( int x, int y ): x( x ), y( y ) {
    this->correct();
}

Rational::Rational( int x ): x( x ), y( 1 ) {;}

Rational::Rational( Rational const & r) {
    x = r.x;
    y = r.y;
    this->correct();
}

Rational & Rational::operator =( Rational const & r ) {
    x = r.x;
    y = r.y;
}

Rational::operator double() const {
    return (double)x/(double)y;
}

Rational & Rational::operator +=(Rational const & r) {
    x = x*r.y+ r.x*y;
    y = y*r.y;
    this->correct();
}

Rational & Rational::operator -=(Rational const & r) {
    this->operator +=( -r );
}

Rational const Rational::operator-() const {
    return Rational( -x, y);
}

Rational & Rational::operator *=( Rational const & r ) {
    x *= r.x;
    y *= r.y;
    this->correct();
}

Rational & Rational::operator /=( Rational const & r ) {
    x *= r.y;
    y *= r.x;
    this->correct();
}

Rational& Rational::operator ++() {
    x += y;
    this->correct();
    return *this;
}

Rational Rational::operator++(int) {
    Rational tmp(*this);
    this->operator ++();
    return tmp;
}

Rational& Rational::operator--() {
    x -= y;
    this->correct();
    return *this;
}

Rational Rational::operator--(int) {
    Rational tmp(*this);
    this->operator --();
    return tmp;
}

void Rational::print() const {
    std::cout<<x<<"/"<<y<<std::endl; 
}

void Rational::correct_sign() {
    if(y < 0) {
        x*= (-1);
        y*= (-1);
    }
}

int Rational::gcd (int a, int b) {
    return b ? gcd (b, a % b) : a;
}

void Rational::correct() {
    this->correct_sign();
    int _gcd = this->gcd(abs(x), y);
    x/=_gcd;
    y/=_gcd;
}


Rational operator+ (const Rational& a, const Rational& b) {
    Rational tmp(a);
    tmp += b;
    return tmp;
}
Rational operator- (const Rational& a, const Rational& b) {
    Rational tmp(a);
    tmp -= b;
    return tmp;
}
Rational operator* (const Rational& a, const Rational& b) {
    Rational tmp(a);
    tmp*=b;
    return tmp;
}
Rational operator/ (const Rational& a, const Rational& b) {
    Rational tmp(a);
    tmp/=b;
    return tmp;
}

bool operator<(const Rational& a, const Rational& b)
{
    if(a.x*b.y < b.x*a.y)
        return true;
    return false;
}

bool operator>(const Rational& a, const Rational& b) {
    return b < a;
}

bool operator>= (const Rational& a, const Rational& b) {
    if(!(a<b))
        return true;
    return false;
}

bool operator<= (const Rational& a, const Rational& b) {
    if(!(a>b))
        return true;
    return false; 
}
bool operator== (const Rational& a, const Rational& b) {
    if(!(a<b) && !(a>b))
        return true;
    return false;
}

bool operator!= (const Rational& a, const Rational& b) {
    if(!(a == b))
        return true;
    return false;
}


